home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / faq-s.zip / PROMPTS.PAS < prev    next >
Pascal/Delphi Source File  |  1991-04-18  |  7KB  |  336 lines

  1. unit prompts;
  2.  
  3. {$R-,S-,I-,D-,F+,V-,B-,L+}
  4.  
  5. interface
  6.  
  7. uses dos,crt,
  8.      general,scrnunit,scrninpt;
  9.  
  10. const maxprompts=50;
  11.  
  12. type prompttype=(number,strng,yesno,command);
  13.      promptrecptr=^promptrec;
  14.      promptrec=record
  15.        ptype:prompttype;
  16.        r1,r2:integer;
  17.        x,y,len,inputwid:integer;
  18.        text:string[80];
  19.        yesnostr:array [false..true] of string[15];
  20.        next,prev:promptrecptr;
  21.        case prompttype of
  22.          command:(dataptr:pointer);
  23.          number:(numberptr:^integer);
  24.          strng:(strptr:^string);
  25.          yesno:(yesnoptr:^boolean)
  26.      end;
  27.  
  28.      promptset=record
  29.        barcolor,datacolor,choicecolor:integer;
  30.        first,last,current:promptrecptr
  31.      end;
  32.  
  33. procedure beginprompts (var p:promptset);
  34. procedure addprompt (var p:promptset; t:prompttype; var data; xx,yy:integer;
  35.                      ptext:string);
  36. procedure setinputwid (var p:promptset; n:integer);
  37. procedure drawprompt (var p:promptset);
  38. procedure drawprompts (var p:promptset);
  39. function  useprompts (var p:promptset):integer;
  40. procedure freeprompts (var p:promptset);
  41. procedure beginchoices (var p:promptset);
  42. procedure addchoice (var p:promptset; ptext:string);
  43. function  usechoices (var p:promptset):integer;
  44. procedure freechoices (var p:promptset);
  45. function bioskey:char;
  46. function bioslook:char;
  47.  
  48. implementation
  49.  
  50.  
  51. function bioslook:char;    (* Returns 255 if not keypressed *)
  52. var r:registers;
  53. begin
  54.   if keypressed then begin
  55.     r.ah:=1;
  56.     intr ($16,r);
  57.     if r.al=0
  58.       then bioslook:=chr(r.ah+128)
  59.       else bioslook:=chr(r.al)
  60.   end else bioslook:=#255
  61. end;
  62.  
  63. function bioswait:char;    (* Waits for a key but doesn't take it out *)
  64. var k:char;
  65. begin
  66.   repeat
  67.     k:=bioslook
  68.   until ord(k)<>255;
  69.   bioswait:=k
  70. end;
  71.  
  72. function bioskey:char;
  73. var r:registers;
  74. begin
  75.   r.ah:=0;
  76.   intr ($16,r);
  77.   if r.al=0
  78.     then bioskey:=chr(r.ah+128)
  79.     else bioskey:=chr(r.al)
  80. end;
  81.  
  82. procedure beginprompts (var p:promptset);
  83. begin
  84.   with curwindowptr^ do begin
  85.     p.barcolor:=barcolor;
  86.     p.datacolor:=datacolor;
  87.     p.choicecolor:=choicecolor
  88.   end;
  89.   p.first:=nil;
  90.   p.last:=nil;
  91.   p.current:=nil
  92. end;
  93.  
  94. procedure addprompt (var p:promptset; t:prompttype; var data; xx,yy:integer;
  95.                      ptext:string);
  96. var n:integer;
  97.     np:promptrecptr;
  98. begin
  99.   new (np);
  100.   if p.first=nil
  101.     then
  102.       begin
  103.         p.first:=np;
  104.         p.last:=np;
  105.         p.current:=np;
  106.         np^.prev:=np;
  107.         np^.next:=np
  108.       end
  109.     else
  110.       begin
  111.         p.first^.prev:=np;
  112.         p.last^.next:=np;
  113.         np^.prev:=p.last;
  114.         np^.next:=p.first;
  115.         p.last:=np
  116.       end;
  117.   with np^ do begin
  118.     ptype:=t;
  119.     x:=xx;
  120.     y:=yy;
  121.     len:=length(ptext);
  122.     dataptr:=@data;
  123.     text:=ptext;
  124.     inputwid:=curwindowptr^.xsize-x-len;
  125.     if inputwid<3 then begin
  126.       writeln ('Not enough room for input box for prompt');
  127.       halt (1)
  128.     end;
  129.     case t of
  130.       strng:r1:=80;
  131.       number:begin
  132.         r1:=-maxint;
  133.         r2:=maxint
  134.       end;
  135.       yesno:begin
  136.         yesnostr[false]:='No';
  137.         yesnostr[true]:='Yes'
  138.       end
  139.     end
  140.   end
  141. end;
  142.  
  143. procedure setinputwid (var p:promptset; n:integer);
  144. begin
  145.   p.last^.inputwid:=n
  146. end;
  147.  
  148. function promptstr (var p:promptrec):string;
  149. begin
  150.   with p do
  151.     case ptype of
  152.       number:promptstr:=strr(numberptr^);
  153.       strng:promptstr:=copy(strptr^,1,80);
  154.       yesno:promptstr:=yesnostr[yesnoptr^];
  155.       command:promptstr:='';
  156.     end
  157. end;
  158.  
  159. procedure drawaprompt (var ps:promptset; var p:promptrec);
  160. var val:string[80];
  161. begin
  162.   with p do begin
  163.     if inputwid>80 then begin
  164.       writeln ('Invalid prompt');
  165.       halt
  166.     end;
  167.     setcolor (ps.choicecolor);
  168.     gotoxy (x,y);
  169.     write (text);
  170.     gotoxy (x+len,y);
  171.     val:=copy(promptstr(p),1,inputwid);
  172.     while length(val)<inputwid do val:=val+' ';
  173.     setcolor (ps.datacolor);
  174.     write (val);
  175.   end
  176. end;
  177.  
  178. procedure drawprompt (var p:promptset);
  179. begin
  180.   if p.last<>nil
  181.     then drawaprompt (p,p.last^)
  182. end;
  183.  
  184. procedure drawprompts (var p:promptset);
  185. var pp,cnt,ns:promptrecptr;
  186. begin
  187.   pp:=p.first;
  188.   if pp=nil then exit;
  189.   repeat
  190.     drawaprompt (p,pp^);
  191.     pp:=pp^.next
  192.   until pp=p.first
  193. end;
  194.  
  195. function useprompts (var p:promptset):integer;
  196. var done:boolean;
  197.     k:char;
  198.     cp:promptrecptr;
  199. const inputable:set of prompttype=[strng,number];
  200.  
  201.   procedure imdone (retval:integer);
  202.   begin
  203.     useprompts:=retval;
  204.     p.current:=cp;
  205.     done:=true
  206.   end;
  207.  
  208.   procedure getinput;
  209.   var x:string;
  210.   begin
  211.     if cp^.ptype in inputable then begin
  212.       setinputregion (cp^.x+cp^.len,cp^.x+cp^.len+cp^.inputwid-1,cp^.y);
  213.       case cp^.ptype of
  214.         strng:buflen:=cp^.r1;
  215.         number:buflen:=6
  216.       end;
  217.       readln (x);
  218.       case cp^.ptype of
  219.         strng:cp^.strptr^:=x;
  220.         number:cp^.numberptr^:=valu(x)
  221.       end;
  222.       drawaprompt (p,cp^)
  223.     end
  224.   end;
  225.  
  226.   procedure selected;
  227.   var pp:promptrecptr;
  228.       n:integer;
  229.   begin
  230.     pp:=p.first;
  231.     n:=1;
  232.     while pp<>cp do begin
  233.       n:=n+1;
  234.       pp:=pp^.next;
  235.       if pp=p.first then halt(2)
  236.     end;
  237.     imdone (n)
  238.   end;
  239.  
  240.   procedure normal (k:char);
  241.   begin
  242.     if (k>=#32) and (k<=#126) and (cp^.ptype in inputable) then begin
  243.       getinput;
  244.       exit
  245.     end;
  246.     case k of
  247.       #27:imdone (0);
  248.       #13:if cp^.ptype in inputable
  249.             then
  250.               begin
  251.                 k:=bioskey;
  252.                 setdefaultinput (promptstr(cp^));
  253.                 getinput
  254.               end
  255.             else selected;
  256.       else selected
  257.     end
  258.   end;
  259.  
  260.   procedure extended (code:integer);
  261.   var k:char;
  262.   begin
  263.     case code of
  264.       72,75:cp:=cp^.prev;
  265.       77,80:cp:=cp^.next;
  266.       71:cp:=p.first;
  267.       79:cp:=p.last;
  268.       end;{else} begin
  269.         selected;
  270.         exit
  271.     {  end}
  272.     end;
  273.     k:=bioskey
  274.   end;
  275.  
  276. begin
  277.   cp:=p.current;
  278.   if cp=nil then cp:=p.first;
  279.   if cp=nil then begin
  280.     useprompts:=0;
  281.     exit
  282.   end;
  283.   done:=false;
  284.   repeat
  285.     colorregion (cp^.x,cp^.x+{cp^.}25{len-1},cp^.y,p.barcolor);
  286.     k:=bioswait;
  287.     colorregion (cp^.x,cp^.x+{cp^.}25{len-1},cp^.y,p.choicecolor);
  288.     if ord(k)>127 then extended(ord(k)-128) else normal(k)
  289.   until done
  290. end;
  291.  
  292. procedure freeprompts (var p:promptset);
  293. var pp,n:promptrecptr;
  294. begin
  295.   pp:=p.first;
  296.   if pp=nil then exit;
  297.   repeat
  298.     n:=pp^.next;
  299.     dispose (pp);
  300.     pp:=n
  301.   until pp=p.first;
  302.   p.first:=nil
  303. end;
  304.  
  305. procedure beginchoices (var p:promptset);
  306. begin
  307.   beginprompts (p)
  308. end;
  309.  
  310. procedure addchoice (var p:promptset; ptext:string);
  311. var y:integer;
  312. begin
  313.   if p.last=nil
  314.     then y:=1
  315.     else y:=p.last^.y+1;
  316.   addprompt (p,command,p,2,y,ptext)
  317. end;
  318.  
  319. function usechoices (var p:promptset):integer;
  320. var n:integer;
  321.     k:char;
  322. begin
  323.   drawprompts (p);
  324.   repeat
  325.     usechoices:=useprompts (p)
  326.   until bioskey in [#27,#13]
  327. end;
  328.  
  329. procedure freechoices (var p:promptset);
  330. begin
  331.   freeprompts (p)
  332. end;
  333.  
  334. end.
  335.  
  336.